import kNN

from matplotlib.font_manager import FontProperties
import matplotlib.lines as mlines
import matplotlib.pyplot as plt
import numpy as np

def showdatas(datingDataMat, datingLabels):
    # 设置汉字字体，避免乱码
    font = FontProperties(fname=r"/Library/Fonts/Songti.ttc", size=14)
    # 将fig画布分隔成1行3列,被分为3个区域,axs[0]表示第一个区域。（也可分成2行2列成为4个区域，axs[0][0]表示第一个区域）
    fig, axs = plt.subplots(nrows=1, ncols=3, sharex=False, sharey=False, figsize=(18, 6))

    LabelsColors = []
    # 标签分类中：1代表没有魅力,2代表魅力一般,3代表极具魅力
    for i in datingLabels:
        if i == 1:
            LabelsColors.append('black')
        if i == 2:
            LabelsColors.append('orange')
        if i == 3:
            LabelsColors.append('red')
    # 散点图1,以datingDataMat矩阵的第1、2列
    axs[0].scatter(x=datingDataMat[:, 0], y=datingDataMat[:, 1], color=LabelsColors, s=15, alpha=.5)
    # 设置标题,x轴label,y轴label
    axs0_xlabel_text = axs[0].set_xlabel(u'每年获得的飞行常客里程数', FontProperties=font)
    axs0_ylabel_text = axs[0].set_ylabel(u'玩视频游戏所消耗时间占', FontProperties=font)
    plt.setp(axs0_xlabel_text, size=10, weight='bold', color='black')
    plt.setp(axs0_ylabel_text, size=10, weight='bold', color='black')

    # 散点图2,以datingDataMat矩阵1、3列
    axs[1].scatter(x=datingDataMat[:, 0], y=datingDataMat[:, 2], color=LabelsColors, s=15, alpha=.5)
    axs1_xlabel_text = axs[1].set_xlabel(u'每年获得的飞行常客里程数', FontProperties=font)
    axs1_ylabel_text = axs[1].set_ylabel(u'每周消费的冰激淋公升数', FontProperties=font)
    plt.setp(axs1_xlabel_text, size=10, weight='bold', color='black')
    plt.setp(axs1_ylabel_text, size=10, weight='bold', color='black')

    # 散点图3,以datingDataMat矩阵的第2、3列
    axs[2].scatter(x=datingDataMat[:, 1], y=datingDataMat[:, 2], color=LabelsColors, s=15, alpha=.5)
    axs2_xlabel_text = axs[2].set_xlabel(u'玩视频游戏所消耗时间占比', FontProperties=font)
    axs2_ylabel_text = axs[2].set_ylabel(u'每周消费的冰激淋公升数', FontProperties=font)
    plt.setp(axs2_xlabel_text, size=10, weight='bold', color='black')
    plt.setp(axs2_ylabel_text, size=10, weight='bold', color='black')

    # 设置图例
    didntLike = mlines.Line2D([], [], color='black', marker='.',
                              markersize=6, label='didntLike')
    smallDoses = mlines.Line2D([], [], color='orange', marker='.',
                               markersize=6, label='smallDoses')
    largeDoses = mlines.Line2D([], [], color='red', marker='.',
                               markersize=6, label='largeDoses')
    axs[0].legend(handles=[didntLike, smallDoses, largeDoses])
    axs[1].legend(handles=[didntLike, smallDoses, largeDoses])
    axs[2].legend(handles=[didntLike, smallDoses, largeDoses])
    # 显示图片
    plt.show()

def datingClassTest():
    #取10%比例数据进行测试
    hoRatio = 0.10
    datingDataMat,datingLabels = kNN.file2matrix('datingDataSet.txt')
    normMat, ranges, minVals = kNN.autoNorm(datingDataMat)
    m = normMat.shape[0]
    numTestVecs = int(m*hoRatio)
    errorCount = 0.0
    for i in range(numTestVecs):
        classifierResult = kNN.classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)
        print("分类器计算结果: %d, 真正答案: %d" % (classifierResult, datingLabels[i]))
        if (classifierResult != datingLabels[i]): errorCount += 1.0
    print("错误率: %f" % (errorCount/float(numTestVecs)))
    print ("错误数: %d" % errorCount)

def classifyMan(man):
    #输出结果
    resultList = ['没有魅力','魅力一般','极具魅力']
    #打开的文件名
    filename = "datingDataSet.txt"
    #打开并处理数据
    datingDataMat, datingLabels = kNN.file2matrix("datingDataSet.txt")
    #训练集归一化
    normMat, ranges, minVals = kNN.autoNorm(datingDataMat)
    #测试集归一化
    norminArr = (man - minVals) / ranges
    #返回分类结果
    classifierResult = kNN.classify0(norminArr, normMat, datingLabels, 3)
    #打印结果
    return resultList[classifierResult-1]

if __name__ == '__main__':
    datingDataMat,datingLabels = kNN.file2matrix('datingDataSet.txt')
    #可视化展示
    showdatas(datingDataMat, datingLabels)
    #分类器测试
    datingClassTest()

    #使用kNN算法分类
    man1=np.array([ 4000,4, 1.1])
    man2=np.array([ 20000,15, 1.1])
    print("man1 is : %s" % classifyMan(man1))
    print("man2 is : %s" % classifyMan(man2))
